<!--
 * @description: 指南针
 * @fileName: index.vue
 * @author: ssr
 * @date: 2023-01-05 10:31:16
 * @version: V1.0.0
! -->
<script lang="ts">
import _ from "lodash"
import {
  defineComponent,
  nextTick,
  reactive,
  ref,
  toRefs,
  watch
} from "vue"

export default defineComponent({
  props: {
    rotate: {
      type: Number,
      default: 290
    }
  },
  emits: ["updateRotate"],
  setup(props, { emit }) {
    const compassRef = ref()
    const state = reactive<{
      isDown: boolean
      rotate: number
    }>({
      isDown: false,
      rotate: 290
    })
    const methods = {
      calculateDegree(x, y) {
        const setup_angle = compassRef.value
        let centerX = -~(setup_angle.offsetHeight || setup_angle.height) / 2
        let centerY = -~(setup_angle.offsetWidth || setup_angle.height) / 2
        // 根据当前坐标和中心坐标计算角度
        const radians = Math.atan2(x - centerX, y - centerY)
        return radians * (180 / Math.PI) * -1 + 180
      },
      handleClick(e) {
        let angle = methods.calculateDegree(e.offsetX, e.offsetY)
        nextTick(() => {
          state.rotate = -~angle
          emit("updateRotate", state.rotate)
        })
      },
      mouseDown() {
        state.isDown = true
      },
      mouseMove(e) {
        if (!state.isDown) {
          return
        }
        let angle = methods.calculateDegree(e.offsetX, e.offsetY)
        nextTick(() => {
          state.rotate = -~angle
          emit("updateRotate", state.rotate)
        })
      },
      mouseUp() {
        state.isDown = false
      },
      mouseLeave() {
        state.isDown = false
      }
    }

    watch(
      () => props.rotate,
      (newVal) => {
        state.rotate = newVal
      }
    )

    return {
      compassRef,
      ...methods,
      ...toRefs(state)
    }
  }
})
</script>

<template>
  <div class="custom-compass" @mouseleave="mouseLeave">
    <span class="direction N">N</span>
    <div class="custom-compass-center">
      <span class="direction W">W</span>
      <span class="direction E">E</span>
    </div>
    <div
      class="custom-compass-back"
      ref="compassRef"
      @mousedown="mouseDown"
      @mousemove="mouseMove"
      @mouseup="mouseUp"
      @click="handleClick"
    >
      <SvgIcon
        name="preserve-color/compass"
        class="svg-compass"
        :style="{ transform: `rotate(${rotate}deg)` }"
      />
    </div>
    <span class="direction S">S</span>
  </div>
</template>

<style lang="scss" scoped>
.custom-compass {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background-color: white;
  // border: 1px solid #2c3649;
  width: 100px;
  height: 100px;
  color: black;
  position: relative;

  .direction {
    display: flex;
    justify-content: center;
    line-height: 18px;
    height: 18px;
    user-select: none;

    &.W,
    &.E {
      width: 18px;
    }
  }
}

.custom-compass-center {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.custom-compass-back {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  top: 18px;
  left: 18px;
  width: 64px;
  height: 64px;
  border-radius: 32px;
  border: 5px solid antiquewhite;
  cursor: pointer;
}

.svg-compass {
  width: 42px !important;
  height: 42px !important;
}
</style>
